﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace mForum.Core.Infrastructure.EventAggregator
{
    using mForum.Core.Common;
    using mForum.Core.Extensions;

    public class EventAggregator : IEventAggregator
    {
        private readonly SynchronizationContext _context;
        private readonly IListenerService _listenerService;

        public EventAggregator(SynchronizationContext context, IListenerService listenerService)
        {
            Check.Argument.IsNotNull(context, "context");
            Check.Argument.IsNotNull(listenerService, "listenerService");
            
            _context = context;
            _listenerService = listenerService;
        }
        
        public void SendMessage<T>(T message) where T : IEvent
        {
            var listeners = _listenerService.GetListeners<T>();

            SendAction(() => listeners.ForEach(x => SendMessageToListeners<T>(x, message)));
        }

        private void SendMessageToListeners<T>(IListenTo<T> x, T message) where T : IEvent
        {
            x.Handle(message);
        }

        private void SendAction(Action action)
        {
            _context.Send(state => action(), null);
        }
    }
}
